use std::time::{Duration, Instant};
use crate::compute::parallel::simd::*;
use crate::compute::parallel::simd_advanced::*;

/// 性能测试结果
#[derive(Debug, Clone)]
pub struct BenchmarkResult {
    pub name: String,
    pub duration_ns: u128,
    pub iterations: usize,
    pub ns_per_op: f64,
    pub mb_per_sec: Option<f64>,
    pub data_size: Option<usize>,
}

impl BenchmarkResult {
    /// 创建新的性能测试结果
    pub fn new(name: &str, duration: Duration, iterations: usize) -> Self {
        BenchmarkResult {
            name: name.to_string(),
            duration_ns: duration.as_nanos(),
            iterations,
            ns_per_op: duration.as_nanos() as f64 / iterations as f64,
            mb_per_sec: None,
            data_size: None,
        }
    }

    /// 设置数据大小，用于计算吞吐量
    pub fn with_data_size(mut self, size_bytes: usize) -> Self {
        self.data_size = Some(size_bytes);
        if size_bytes > 0 {
            let seconds = self.duration_ns as f64 / 1_000_000_000.0;
            let mb = size_bytes as f64 / (1024.0 * 1024.0);
            self.mb_per_sec = Some(mb / seconds);
        }
        self
    }

    /// 格式化结果
    pub fn format(&self) -> String {
        let mut result = format!(
            "{}: {} iterations in {:?} ns ({:.2} ns/op)",
            self.name, self.iterations, self.duration_ns, self.ns_per_op
        );

        if let Some(mb_per_sec) = self.mb_per_sec {
            result.push_str(&format!(", {:.2} MB/s", mb_per_sec));
        }

        result
    }
}

/// 性能测试函数
pub fn run_benchmark<F>(name: &str, iterations: usize, f: F) -> BenchmarkResult
where
    F: Fn(),
{
    // 预热
    for _ in 0..iterations / 10 {
        f();
    }

    // 实际测试
    let start = Instant::now();
    for _ in 0..iterations {
        f();
    }
    let duration = start.elapsed();

    BenchmarkResult::new(name, duration, iterations)
}

/// 生成测试数据
pub fn generate_test_data(size: usize) -> Vec<f64> {
    let mut data = Vec::with_capacity(size);
    for i in 0..size {
        let value = (i as f64).sin() * 100.0 + 1000.0;
        data.push(value);
    }
    data
}

/// 比较不同SIMD实现的向量点乘性能
pub fn benchmark_dot_product(data_size: usize, iterations: usize) -> Vec<BenchmarkResult> {
    let a = generate_test_data(data_size);
    let b = generate_test_data(data_size);
    let data_bytes = data_size * std::mem::size_of::<f64>() * 2;

    let mut results = Vec::new();

    // 测试标量实现
    let scalar_result = run_benchmark("Scalar Dot Product", iterations, || {
        let _result = a.iter().zip(b.iter()).map(|(&x, &y)| x * y).sum::<f64>();
    }).with_data_size(data_bytes);
    results.push(scalar_result);

    // 测试AVX2实现
    if is_avx_supported() {
        let avx_result = run_benchmark("AVX2 Dot Product", iterations, || {
            unsafe {
                let _result = vector_dot_product(&a, &b);
            }
        }).with_data_size(data_bytes);
        results.push(avx_result);
    }

    results
}

/// 比较不同SIMD实现的EMA性能
pub fn benchmark_ema(data_size: usize, iterations: usize) -> Vec<BenchmarkResult> {
    let data = generate_test_data(data_size);
    let alpha = 0.2;
    let data_bytes = data_size * std::mem::size_of::<f64>();

    let mut results = Vec::new();

    // 测试标量实现
    let scalar_result = run_benchmark("Scalar EMA", iterations, || {
        let mut result = Vec::with_capacity(data.len());
        result.push(data[0]);
        
        let mut prev_ema = data[0];
        for &value in &data[1..] {
            let ema = alpha * value + (1.0 - alpha) * prev_ema;
            result.push(ema);
            prev_ema = ema;
        }
    }).with_data_size(data_bytes);
    results.push(scalar_result);

    // 测试AVX2实现
    if is_avx_supported() {
        let avx_result = run_benchmark("AVX2 EMA", iterations, || {
            unsafe {
                let _result = vector_ema(&data, alpha);
            }
        }).with_data_size(data_bytes);
        results.push(avx_result);
    }

    results
}

/// 比较不同SIMD实现的MACD性能
pub fn benchmark_macd(data_size: usize, iterations: usize) -> Vec<BenchmarkResult> {
    let data = generate_test_data(data_size);
    let data_bytes = data_size * std::mem::size_of::<f64>();

    let mut results = Vec::new();

    // 测试标量实现
    let scalar_result = run_benchmark("Scalar MACD", iterations, || {
        let _result = compute_macd_fallback(&data, 12, 26, 9);
    }).with_data_size(data_bytes);
    results.push(scalar_result);

    // 测试AVX512实现
    if is_x86_feature_detected!("avx512f") {
        let avx512_result = run_benchmark("AVX512 MACD", iterations, || {
            unsafe {
                let _result = compute_macd_avx512(&data, 12, 26, 9);
            }
        }).with_data_size(data_bytes);
        results.push(avx512_result);
    }

    results
}

/// 比较不同SIMD实现的布林带性能
pub fn benchmark_bollinger_bands(data_size: usize, iterations: usize) -> Vec<BenchmarkResult> {
    let data = generate_test_data(data_size);
    let data_bytes = data_size * std::mem::size_of::<f64>();

    let mut results = Vec::new();

    // 测试标量实现
    let scalar_result = run_benchmark("Scalar Bollinger Bands", iterations, || {
        let _result = compute_bollinger_bands_fallback(&data, 20, 2.0);
    }).with_data_size(data_bytes);
    results.push(scalar_result);

    // 测试AVX512实现
    if is_x86_feature_detected!("avx512f") {
        let avx512_result = run_benchmark("AVX512 Bollinger Bands", iterations, || {
            unsafe {
                let _result = compute_bollinger_bands_avx512(&data, 20, 2.0);
            }
        }).with_data_size(data_bytes);
        results.push(avx512_result);
    }

    results
}

/// 运行所有基准测试
pub fn run_all_benchmarks() -> Vec<BenchmarkResult> {
    let mut results = Vec::new();

    // 打印CPU特性
    let features = CpuFeatures::detect();
    println!("CPU Features: {:?}", features);

    // 小数据集
    results.extend(benchmark_dot_product(1000, 10000));
    results.extend(benchmark_ema(1000, 10000));
    results.extend(benchmark_macd(1000, 1000));
    results.extend(benchmark_bollinger_bands(1000, 1000));

    // 中等数据集
    results.extend(benchmark_dot_product(10000, 1000));
    results.extend(benchmark_ema(10000, 1000));
    results.extend(benchmark_macd(10000, 100));
    results.extend(benchmark_bollinger_bands(10000, 100));

    // 大数据集
    results.extend(benchmark_dot_product(100000, 100));
    results.extend(benchmark_ema(100000, 100));
    results.extend(benchmark_macd(100000, 10));
    results.extend(benchmark_bollinger_bands(100000, 10));

    // 打印结果
    for result in &results {
        println!("{}", result.format());
    }

    results
}